package com.piece.mall.service;

import com.piece.core.framework.support.bootstrap.DataTable;
import com.piece.core.framework.support.bootstrap.QueryTable;
import com.piece.core.framework.util.collection.MapUtil;
import com.piece.core.framework.util.object.ObjectUtil;
import com.piece.core.jpa.repository.BaseService;
import com.piece.mall.model.PmsAttr;
import com.piece.mall.model.PmsAttrGroupRelation;
import com.piece.mall.repository.PmsAttrGroupRelationRepository;
import com.piece.mall.repository.PmsAttrRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class PmsAttrService extends BaseService<PmsAttr, String> {

    @Autowired
    private PmsAttrRepository pmsAttrRepository;

    @Autowired
    private PmsAttrGroupRelationRepository pmsAttrGroupRelationRepository;

    @Resource
    private JdbcTemplate jdbcTemplate;

    @PostConstruct
    public void initRepository() {
        setRepository(pmsAttrRepository);
    }

    @Override
    public PmsAttr insertOrUpdate(PmsAttr attr) throws Exception {
        Long groupId = attr.getAttrGroupId();
        if (null == attr.getAttrId()) {
            attr = pmsAttrRepository.insert(attr);
        } else {
            pmsAttrRepository.update(attr);
        }

        if (null != groupId) {
            // 添加属性分组关联关系
            PmsAttrGroupRelation relation = pmsAttrGroupRelationRepository.findOneByCondition(MapUtil.builder(new HashMap<String, Object>())
                    .put("attrGroupId", groupId).put("attrId", attr.getAttrId()).build());
            if (null == relation) {
                String sql = "select ifnull(max(attr_sort) + 1,1) from pms_attr_group_relation where attr_group_id=?";
                Long sort = jdbcTemplate.queryForObject(sql, Long.class, groupId);
                relation = new PmsAttrGroupRelation();
                relation.setAttrId(attr.getAttrId());
                relation.setAttrGroupId(groupId);
                relation.setAttrSort(sort);
                pmsAttrGroupRelationRepository.insert(relation);
            }
        }

        return attr;
    }

    /**
     * 查询属性分组关联的所有属性分页数据
     */
    public DataTable<PmsAttr> findRelationPage(QueryTable queryTable, Long groupId) {
        String hql = "select attr.* from `pms_attr` attr " +
                " inner join `pms_attr_group_relation` r on r.attr_id = attr.attr_id and r.attr_group_id = " + groupId;
        queryTable.setAlias("attr");
        queryTable.setHql(hql);
        return pmsAttrRepository.findPageBySql(queryTable);
    }

    /**
     * 查询属性分组未关联的所有属性分页数据
     */
    public DataTable<PmsAttr> findUnRelationPage(QueryTable queryTable, Long groupId) {
        String hql = "select attr.* from `pms_attr` attr " +
                " left join `pms_attr_group` g on g.catalog_id = attr.catalog_id and g.attr_group_id = " + groupId +
                " where attr.attr_id not in( " +
                " select r.attr_id from `pms_attr_group_relation` r where r.attr_group_id = " + groupId + ")";
        queryTable.setAlias("attr");
        queryTable.setHql(hql);
        return pmsAttrRepository.findPageBySql(queryTable);
    }

    /**
     * 查询属性分组关联的属性信息
     */
    public List<PmsAttr> getRelationAttr(Long groupId, Integer attrType) {
        // 根据分组id查询所有关联关系
        List<PmsAttrGroupRelation> relations = pmsAttrGroupRelationRepository.findByCondition(MapUtil.builder(new HashMap<String, Object>())
                .put("Q_attrGroupId_L_EQ", groupId).build(), null);
        List<Long> attrIds = relations.stream().map(relation -> relation.getAttrId()).collect(Collectors.toList());

        if (ObjectUtil.isEmpty(attrIds)) {
            return new ArrayList<>();
        }

        Map<String, Object> params = new HashMap<>();
        params.put("Q_attrId_L_IN", attrIds);
        if (null != attrType) {
            params.put("Q_attrType_S_EQ", attrType);
        }

        return pmsAttrRepository.findByCondition(params, null);
    }

    @Override
    public void delete(Serializable id) throws Exception {
        PmsAttr attr = findById(id);
        pmsAttrRepository.delete(id);
        if (null != attr.getAttrGroupId()) {
            deleteGroupRelation(attr.getAttrGroupId(), Arrays.asList(new Long[]{attr.getAttrId()}));
        }
    }

    @Override
    public int delete(Serializable[] ids) throws Exception {
        PmsAttr attr = findById(ids[0]);
        int size = pmsAttrRepository.delete(ids);
        if (null != attr.getAttrGroupId()) {
            deleteGroupRelation(attr.getAttrGroupId(), Arrays.asList(ids));
        }
        return size;
    }

    private void deleteGroupRelation(Long groupId, List attrIds) {
        String sql = "delete from pms_attr_group_relation where attr_group_id=? and attr_id in(?)";
        jdbcTemplate.update(sql, new Object[]{ groupId, attrIds });
    }
}
